package org.nf.trading.interceptor;

import com.fasterxml.jackson.databind.ObjectMapper;

import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.UnsupportedJwtException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.nf.trading.util.JwtUtils;
import org.nf.trading.vo.ResultVO;
import org.springframework.http.HttpStatus;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import java.io.IOException;


public class LoginInterceptor implements HandlerInterceptor {
    /**
     * 请求头的name
     */
    private static final String HEADER = "Authorization";
    /**
     * token前缀，注意有个空格
     */
    private static final String TOKEN_PREFIX = "Bearer ";

    /**
     * 当请求方法是OPTIONS的时候（预检请求）
     * @param request
     * @param response
     * @param handler -> 默认是HandlerMethod，但是如果出现跨域或者是预检请求的时候，这个handler
     *                   就会变为PreFlightHandler对象，这个对象就是专门用于处理预检请求，同时还对
     *                   预检处理进行跨域设置。而且这个对象是在执行完所有拦截器的preHandler方法之后才执行
     *                   所以当遇到预检请求时，应该直接放行，否则预检请求同样会出现跨域的问题
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //如果此时的handler不是HandlerMethod对象的时候就放行
        if(!(handler instanceof HandlerMethod)) {
            return true;
        }
        //解析token
        String token = request.getHeader(HEADER);
        if(token != null) {
            //得到jwt
            String jwt = token.replace(TOKEN_PREFIX, "");
            //验证token,验证未通过会引发相关异常
            try {
                System.out.println("拦截器拦截了");
                JwtUtils.verify(jwt);
                //获取载体数据
                Integer uid = JwtUtils.getPayload(jwt, "uid", Integer.class);
                //将其保存到请求作用域,在controller中就可以通过@RequestAttribute注解获取到
                request.setAttribute("uid", uid);
                //放行
                return true;
            } catch (SecurityException e) {
                responseView(response, "无效的签名");
                /*MalformedJwtException*/
            } catch (MalformedJwtException e) {
                responseView(response, "无效的token");
            } catch(ExpiredJwtException e) {
                responseView(response, "Token已过期");
            } catch(UnsupportedJwtException e) {
                responseView(response, "不支持的Token类型");
            }
            return false;
        }
        //没有token表示未登录
        responseView(response, "请先登陆");
        return false;
    }
    /**
     * 统一响应视图
     * @param response
     * @param message
     */
    private void responseView(HttpServletResponse response, String message) throws IOException {
        ResultVO vo = new ResultVO();
        vo.setCode(HttpStatus.UNAUTHORIZED.value());
        vo.setMessage(message);
        response.setContentType("application/json;charset=utf-8");
        String json = new ObjectMapper().writeValueAsString(vo);
        response.getWriter().println(json);
    }
}
